package com.kfm.login.interceptor;

import com.kfm.login.util.Constant;
import com.kfm.login.util.IPUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
 * 频繁发送请求，拉黑
 */
@Component
@Slf4j
public class AccessCountInterceptor implements HandlerInterceptor {

    // redis 存储的值
    // redis:login:ip -- 登录请求失败的次数
    // redis:black:ip  -- 黑名单
    // redis:access:ip -- 指定时间的访问次数
    @Resource
    private RedisTemplate<String, Integer> redisTemplate;

    @Value("${login.maxAccessTime}")
    private Integer maxAccessTime;
    @Value("${login.maxAccessCount}")
    private Integer maxAccessCount;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info(request.getRequestURI());
        String ip = IPUtils.getIpAddress(request);
        String key = Constant.REDIS_ACCESS_PREFIX + ip;
        Integer count = redisTemplate.opsForValue().get(key);
        if (count == null) {
            // 一秒钟发送的请求次数  ip 次数
            redisTemplate.opsForValue().set(key, 1, maxAccessTime, TimeUnit.SECONDS);
            return true;
        }
        count = count + 1;
        if (count >= maxAccessCount) {
            // 超过指定时间的指定访问次数,加入黑名单
            redisTemplate.opsForValue().set(Constant.REDIS_BLACK_PREFIX + ip, 1, 24, TimeUnit.HOURS);
            return true;
        }
        // offset 修改key对应的值，key过期的时间不做修改
        // set(key,value) -- 如果没有key直接存储，如果有 覆盖掉， 1--10 2-
        // set(key,value,offset) offset 修改key对应的值，key过期的时间不做修改
        redisTemplate.opsForValue().set(key, count, 0);
        return true;

    }
}
